Fix CUDA arch selection and provide a portable arch list - #280
Draft
xashr wants to merge 1 commit into
Draft
Conversation
Without an explicit CMAKE_CUDA_ARCHITECTURES, enable_language(CUDA) (CMP0104 NEW) seeds it from nvcc's default arch (sm_75 on CUDA 13, sm_52 on CUDA 12) - it does not query the local GPU - so every build without an explicit list was single-arch, e.g. sm_75 even on an RTX 5090. Default to the llama.cpp/ggml-cuda arch list before that call. The Dockerfile gets a CUDA_DOCKER_ARCH build-arg passthrough for custom arch sets instead of defining its own list.
xashr
marked this pull request as draft
August 19, 2026 20:46
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
All CUDA builds based on the CMakeLists.txt that do not explicitly set
CMAKE_CUDA_ARCHITECTURESare only built for nvcc's default architecture: sm_75 on CUDA 13, sm_52 on CUDA 12.The fallback to set
CMAKE_CUDA_ARCHITECTURES=nativeis never reached (and in addition is only supported on CMake >= 3.24).=> For local builds this means: built for sm_75 (CUDA 13) / sm_52 (CUDA 12), even on an RTX 5090 (sm_120).
=> For Docker builds this also means: no portable set of architectures is built, only the minimal sm_52 or sm_75.
The Windows prebuilts are not affected (they pass a curated arch list);
build_windows.ps1 autoexplicitly targets the local GPU when one is present.Root cause
We set
cmake_minimum_required(VERSION 3.20)which activates policy CMP0104: duringenable_language(CUDA), CMake auto-initializesCMAKE_CUDA_ARCHITECTURESfrom nvcc's compile default whenever the user doesn't set it. The seed comes from the compiler-id probe - it does not query the local GPU. It is sm_75 on CUDA 13, sm_52 on CUDA 12.Example (CUDA 12):
-- Using CMAKE_CUDA_ARCHITECTURES=52 CMAKE_CUDA_ARCHITECTURES_NATIVE=120a-real-- Using CMAKE_CUDA_ARCHITECTURES=52 CMAKE_CUDA_ARCHITECTURES_NATIVE=No CUDA devices found.-realSince
CMAKE_CUDA_ARCHITECTURESis initialized by CMake, the fallback to "native" is never used:Solution
This PR brings the implementation closer to llama.cpp:
CMAKE_CUDA_ARCHITECTURESis not set.CMAKE_CUDA_ARCHITECTURES=native(CMake >= 3.24) or by defining a custom set, e.g.CMAKE_CUDA_ARCHITECTURES=120a-realFor Docker builds we do not set
CMAKE_CUDA_ARCHITECTURESand thus build for the full defined arch set.Details
enable_language(CUDA)in CMakeLists.txt. That is the only point where "the user didn't set anything" is still detectable, because the CMake seed happens inside that call. The old if/else fallback quoted above sat after the seed and was therefore dead code - it is removed, sinceCMAKE_CUDA_ARCHITECTURESautomatically initializes theCUDA_ARCHITECTURESproperty of every CUDA target.-virtual= PTX (compiled on the fly by the driver, forward-compatible),-real= SASS (native machine code).ggml-cudadefault.12Xvalues (e.g.120, ornativeresolved on a Blackwell GPU) are upgraded to12Xa- theavariant unlocks Blackwell's FP4 tensor cores. Each replacement is logged.nativerequires CMake >= 3.24. On CMake 3.20-3.23 it falls back to the default list with a status message (same gate as llama.cpp'sGGML_NATIVE, but visible instead of silently ignored).-- Using CMAKE_CUDA_ARCHITECTURES=...), so the result is easy to verify.CUDAARCHSenvironment variable keeps working (CMake reads it before the seed)..devops/cuda.Dockerfilecontains no arch list at all - CMakeLists.txt is the single source of truth. Custom images can still override via--build-arg CUDA_DOCKER_ARCH="89-real;...".Consequences / Remarks
CMAKE_CUDA_ARCHITECTURES) increase by roughly 4.5x (CUDA 12 Docker build on a 24-core CPU).Open issues / TODO